package cs2340.quarterblack.wheresmystuff;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import cs2340.quarterblack.wheresmystuff.Account.Statustype;
import cs2340.quarterblack.wheresmystuff.Item.Itemtype;

public class LocalStorage extends Storage {
	
	private static HashMap<String, Account> accounts;
	private static HashMap<String, ArrayList<Item>> itemsLost;
	private static HashMap<String, ArrayList<Item>> itemsFound;
	private static boolean accountsInitialized = false;
	private static boolean itemsInitialized = false;
	
	public List<Item>getAllItems()
	{
		return null;
	}
	/**
	 * checks to see if the user login is a valid login
	 * @param tempUser the user account with the login information
	 * to be checked
	 * @return one of the enumerated login responses
	 */
	public loginResponse checkLogin(Account tempUser) {
		if (!accountsInitialized) {
			initializeAccounts();
			accountsInitialized = true;
		}
		
		if (accounts.containsKey(tempUser.getUserId())) {
			Account existingAccount = accounts.get(tempUser.getUserId());
			if (existingAccount.getStatus().equals("unlocked")){
				return loginResponse.ALLOWED;
			}
			if (existingAccount.getPw().equals(tempUser.getPw())) {
				return loginResponse.ALLOWED;
			}
			return loginResponse.INVALID_CREDENTIALS;
		}
		else {
			return loginResponse.INVALID_CREDENTIALS;
		}
	}
	/**
	 * method to give the App the real account, not the one used to login
	 * @param acct the fake account with information needed to access the real account
	 * @return the account being stored in the database
	 */
	public Account getAccount(Account acct)
	{
		if(accounts.containsKey(acct.getUserId()))
		{
			return accounts.get(acct.getUserId());
		}
		return null;
	}
	/**
	 * checks to see if the given id exists in the database
	 * @param id the id to be checked
	 * @return whether or not the id exists 
	 */
	public boolean checkExists(String id)
	{
		if(getAccount(new Account(id,null)) != null)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	/**
	 * adds a new account to the database
	 * @param newUser the user to be added
	 * @return whether or not the user was actually added.
	 */
	public boolean addAccount(Account newUser) {
		if (!accountsInitialized) {
			initializeAccounts();
			accountsInitialized = true;
		}
		if(accounts.containsKey(newUser.getUserId()) == false)
		{
			accounts.put(newUser.getUserId(),newUser);
		}
		else
		{
			return false;
		}
		return true;
	}

	/**
	 * deletes the account with the id from the database
	 * @id the id of the account to be deleted
	 */
	public boolean deleteAccount(String id) {
		if (accounts.containsKey(id)) {
			accounts.remove(id);
			return true;
			}
		else
		{
			return false;
		}
	}
	
	/**
	 * locks the specified account
	 * @param currentUser the account to be locked
	 * @return result whether or not the account was successfully
	 * locked or not
	 */
	public boolean lockAccount(Account currentUser) {
		if (!accountsInitialized) {
			initializeAccounts();
			accountsInitialized = true;
		}
		if (accounts.containsKey(currentUser.getUserId())) {
			Account editingAccount = accounts.get(currentUser.getUserId());
			editingAccount.setStatus(Statustype.locked);
			return true;
			}
			
		return false;
		
	}
	/**
	 * unlocks the specified account
	 * @param currentUser the user to be added to the database
	 * @return result whether or not the user was successfully added to the database
	 */
	public boolean unlockAccount(Account currentUser) {
		if (!accountsInitialized) {
			initializeAccounts();
			accountsInitialized = true;
		}
		if (accounts.containsKey(currentUser.getUserId())) {
			Account editingAccount = accounts.get(currentUser.getUserId());
			editingAccount.setStatus(Statustype.unlocked);
			return true;
			}
		return false;	
		
	}
	
	/**
	 * sets the privileges of an account
	 * @param id  the id of the account to be added.
	 * @param admin the status of the admin variable the account should be set to
	 * @return whether or not the privileges where changed.
	 */
	public boolean setPrivelages(String id,boolean admin)
	{
		if (!accountsInitialized) {
			initializeAccounts();
			accountsInitialized = true;
		}
		if (accounts.containsKey(id)) {
			Account editingAccount = accounts.get(id);
			editingAccount.setAdmin(admin);
			return true;
			}
				
		return false;
	}
	/**
	 * adds the indicated item to either a user's lost list
	 * or their found list
	 * @param newItem the item to be added
	 * @return bool whether the item was successfully added or not
	 */
	public boolean addItem(Item newItem) {
		if (!itemsInitialized) {
			initializeItems();
			itemsInitialized = true;
		}
		if (newItem.getType().equals("Lost")) {
			if (itemsLost.containsKey(newItem.getUserId())) {
				ArrayList<Item> itemList = itemsLost.get(newItem.getUserId());
				itemList.add(newItem);
			}
			else {
				ArrayList<Item> itemList = new ArrayList<Item>();
				itemList.add(newItem);
				itemsLost.put(newItem.getUserId(), itemList);
			}
		}
		else {
			if (itemsFound.containsKey(newItem.getUserId())) {
				ArrayList<Item> itemList = itemsFound.get(newItem.getUserId());
				itemList.add(newItem);
			}
			else {
				ArrayList<Item> itemList = new ArrayList<Item>();
				itemList.add(newItem);
				itemsFound.put(newItem.getUserId(), itemList);
			}
		}
		return true;
	}
	
	/**
	 * returns a list of the user's items
	 * @param currentUser the user who's items should be sent back
	 * @param type the type of item list that should be returned either lost or found
	 */
	public List<Item> getUsersItems(Account currentUser, Itemtype type) {
		if (!itemsInitialized) {
			initializeItems();
			itemsInitialized = true;
		}
		List<Item> results;
		if (type == Itemtype.LOST) {
			results = itemsLost.get(currentUser.getUserId());
		}
		else {
			results = itemsFound.get(currentUser.getUserId());
		}
		return results;
		
	}
	/**
	 * initializes the default accounts
	 */
	private void initializeAccounts() {
		accounts = new HashMap<String,Account>();
		Account a1 = new Account("bob","theman");
		Account a2 = new Account("steve","nottheman");
		Account a3 = new Account("trogdor","hecomesinthenight");
		Account a4 = new Account("pacman","wakawaka");
		Account admin = new Account("admin","admin", true);

		accounts.put("bob", a1);
		accounts.put("steve", a2);
		accounts.put("trogdor", a3);
		accounts.put("pacman", a4);
		accounts.put(admin.getUserId(), admin);
	}

	/**
	 * initializes the default items
	 */
	private void initializeItems() {
		itemsLost = new HashMap<String,ArrayList<Item>>();
		itemsFound = new HashMap<String,ArrayList<Item>>();
		Item i1 = new Item("bob","Item 1");
		Item i2 = new Item("bob","Item 2");
		Item i3 = new Item("bob","Item 3");
		Item i4 = new Item("bob","Item 4");
		Item i5 = new Item("bob","Item 5");
		Item i6 = new Item("steve","Item 6");
		Item i7 = new Item("steve","Item 7");
		Item i8 = new Item("steve","Item 8");
		Item i9 = new Item("trogdor","Item 9");
		Item iA = new Item("pacman","Item A");
		Item iB = new Item("pacman","Item B");
		Item iC = new Item("pacman","Item C");
		
		ArrayList<Item> bobsItems = new ArrayList<Item>();
		bobsItems.add(i1);
		bobsItems.add(i2);
		bobsItems.add(i3);
		bobsItems.add(i4);
		bobsItems.add(i5);
		ArrayList<Item> stevesItems = new ArrayList<Item>();
		stevesItems.add(i6);
		stevesItems.add(i7);
		stevesItems.add(i8);
		ArrayList<Item> trogdorsItems = new ArrayList<Item>();
		trogdorsItems.add(i9);
		ArrayList<Item> pacmansItems = new ArrayList<Item>();
		pacmansItems.add(iA);
		pacmansItems.add(iB);
		pacmansItems.add(iC);
		
		itemsLost.put("bob", bobsItems);
		itemsLost.put("steve", stevesItems);
		itemsLost.put("trogdor", trogdorsItems);
		itemsLost.put("pacman", pacmansItems);
	}

}
